package com.visionet.waveletData.web.service.business;

import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;

import org.apache.commons.httpclient.Cookie;
import org.apache.commons.httpclient.HttpClient;
import org.apache.commons.httpclient.HttpStatus;
import org.apache.commons.httpclient.NameValuePair;
import org.apache.commons.httpclient.SimpleHttpConnectionManager;
import org.apache.commons.httpclient.methods.PostMethod;
import org.apache.commons.httpclient.params.HttpMethodParams;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springside.modules.mapper.JsonMapper;

import com.visionet.waveletData.web.common.utilities.props.PropsKeys;
import com.visionet.waveletData.web.common.utilities.props.PropsUtil;
@Service
@Transactional
public class ChatConnection {
	private static JsonMapper mapper = JsonMapper.nonDefaultMapper();
	private static Logger _log = LoggerFactory.getLogger(ChatConnection.class);
	
	public String dropDatabase(){
		NameValuePair[] postData = createNameValuePair(new HashMap<String,String>());
		
		return connectReturnString("/trust-api/drop-database",postData);
	}
	
	/**
	 * refId : user.id
	 * orgId : user.orgId
	 * loginName : user.loginName
	 * pwd : user.plainPassword
	 * [nickName] : user.aliasName
	 * [profilePhoto] : user.userInfo.userImgUrl
	 * [sex{0,1}] : user.userInfo.gender
	 * @param userMap
	 * @return
	 */
	public boolean signUp(Map<String,String> userMap){
		NameValuePair[] postData = createNameValuePair(userMap);
		
		return connect("/trust-api/signUp",postData);
	}
	
	/**
	 * refId : user.id
	 * [pwd] : user.plainPassword
	 * [nickName] : user.aliasName
	 * [profilePhoto] : user.userInfo.userImgUrl
	 * @param userMap
	 * @return
	 */
	public boolean editUser(Map<String,String> userMap){
		NameValuePair[] postData = createNameValuePair(userMap);
		
		return connect("/trust-api/editUser",postData);
	}
	
	/**
	 * refId : team.id
	 * orgId : team.orgId
	 * name : team.teamName
	 * founderRefId : team.createId
	 * [profilePhoto] : team.teamImgUrl
	 * @param groupMap
	 * @return
	 */
	public boolean createGroup(Map<String,String> groupMap){
		NameValuePair[] postData = createNameValuePair(groupMap);
		
		return connect("/trust-api/createGroup",postData);
	}
	
	/**
	 * refId : team.id
	 * orgId : team.orgId
	 * founderRefId : team.createId
	 * [name] : team.teamName
	 * [profilePhoto] : team.teamImgUrl
	 * @param groupMap
	 * @return
	 */
	public boolean editGroup(Map<String,String> groupMap){
		NameValuePair[] postData = createNameValuePair(groupMap);
		
		return connect("/trust-api/editGroup",postData);
	}
	
	/**
	 * refId : team.id
	 * orgId : team.orgId
	 * founderRefId : team.createId
	 * @param groupMap
	 * @return
	 */
	public boolean disbandGroup(Map<String,String> groupMap){
		NameValuePair[] postData = createNameValuePair(groupMap);
		
		return connect("/trust-api/disbandGroup",postData);
	}
	/**
	 * refId : team.id
	 * orgId : team.orgId
	 * userRefId : user.id
	 * @param groupMap
	 * @return
	 */
	public boolean joinGroup(Map<String,String> groupMap){
		NameValuePair[] postData = createNameValuePair(groupMap);
		
		return connect("/trust-api/joinGroup",postData);
	}
	/**
	 * refId : team.id
	 * orgId : team.orgId
	 * userRefId : user.id
	 * @param groupMap
	 * @return
	 */
	public boolean exitGroup(Map<String,String> groupMap){
		NameValuePair[] postData = createNameValuePair(groupMap);
		
		return connect("/trust-api/exitGroup",postData);
	}
	
	/**
	 * refId : team.id
	 * orgId : team.orgId
	 * @param groupMap
	 * @return
	 */
	public boolean clearGroupMember(Map<String,String> groupMap){
		NameValuePair[] postData = createNameValuePair(groupMap);
		
		return connect("/trust-api/clearGroupMember",postData);
	}
	
	
	/**
	 * refId : team.id
	 * orgId : team.orgId
	 * oldFounderRefId : user.id
	 * newFounderRefId : user.id
	 * @param groupMap
	 * @return
	 */
	public boolean handOver(Map<String,String> groupMap){
		NameValuePair[] postData = createNameValuePair(groupMap);
		
		return connect("/trust-api/handOver",postData);
	}
	
	public boolean importWhisper(Map<String,String> chatMessageMap){
		NameValuePair[] postData = createNameValuePair(chatMessageMap);
		
		return connect("/trust-api/importWhisper",postData);
	}
	
	
	private boolean connect(String url,NameValuePair[] postData){
		boolean result = false;
		
		if("true".equals(PropsUtil.getProperty(PropsKeys.NODE_CHAT_SYNC_DISENABLE))){
			return true;
		}
		
		url = PropsUtil.getProperty(PropsKeys.NODE_CHAT_DOMAIN) + url;
		HttpClient httpClient = new HttpClient(new SimpleHttpConnectionManager(true));
		httpClient.getParams().setParameter(HttpMethodParams.HTTP_CONTENT_CHARSET, "utf-8");
		PostMethod postMethod = new PostMethod(url);
		
		postMethod.setRequestBody(postData);
		
		try {
			int statusCode = httpClient.executeMethod(postMethod);
			
			if(statusCode == HttpStatus.SC_OK || statusCode == HttpStatus.SC_ACCEPTED){
				byte[] responseBody = postMethod.getResponseBody();
				String resultJson = new String(responseBody);
				
				@SuppressWarnings("unchecked")
				Map<String, Object> jsonMap = mapper.fromJson(resultJson, HashMap.class);
				if(jsonMap.containsKey("code") && jsonMap.get("code").equals(10000)){
					result = true;
				}else{
					_log.error("node-chat " + url + " error , json:" + resultJson);
				}
			}else{
				_log.error("node-chat " + url + " statusCode error , statusCode:" + statusCode);
			}
		} catch (Exception e) {
			_log.error("node-chat " + url + " connection fail",e);
		}finally{
			postMethod.releaseConnection();
		}
		
		return result;
	}
	
	public Map<String,String> signIn(Map<String,String> map){
		Map<String,String> result = new HashMap<String,String>();
		String url = "/trust-api/signIn";
		
		int size = map.size(),i = 2;
		NameValuePair[] pair = new NameValuePair[size + 2];
		
		pair[0] = new NameValuePair("appKey",PropsUtil.getProperty(PropsKeys.NODE_CHAT_APPKEY));
		pair[1] = new NameValuePair("masterSecret",PropsUtil.getProperty(PropsKeys.NODE_CHAT_MASTERSECRET));

        Iterator<Map.Entry<String,String>> it = map.entrySet().iterator();
        while(it.hasNext()){
            Map.Entry<String,String> entry = it.next();
            pair[i] = new NameValuePair(entry.getKey(),entry.getValue());
            i++;
        }

		
		
		if("true".equals(PropsUtil.getProperty(PropsKeys.NODE_CHAT_SYNC_DISENABLE))){
			return result;
		}
		
		url = PropsUtil.getProperty(PropsKeys.NODE_CHAT_DOMAIN) + url;
		HttpClient httpClient = new HttpClient(new SimpleHttpConnectionManager(true));
		httpClient.getParams().setParameter(HttpMethodParams.HTTP_CONTENT_CHARSET, "utf-8");
		PostMethod postMethod = new PostMethod(url);
		
		postMethod.setRequestBody(pair);
		
		try {
			int statusCode = httpClient.executeMethod(postMethod);
			
			if(statusCode == HttpStatus.SC_OK || statusCode == HttpStatus.SC_ACCEPTED){
				byte[] responseBody = postMethod.getResponseBody();
				String resultJson = new String(responseBody);
				
				@SuppressWarnings("unchecked")
				Map<String, Object> jsonMap = mapper.fromJson(resultJson, HashMap.class);
				if(jsonMap.containsKey("code") && jsonMap.get("code").equals(10000)){
					Cookie[] cookies = httpClient.getState().getCookies();
					for (Cookie cookie : cookies) {
						result.put(cookie.getName(), cookie.getValue());
					}
				}else{
					_log.error("node-chat " + url + " error , json:" + resultJson);
				}
			}else{
				_log.error("node-chat " + url + " statusCode error , statusCode:" + statusCode);
			}
		} catch (Exception e) {
			_log.error("node-chat " + url + " connection fail",e);
		}finally{
			postMethod.releaseConnection();
		}
		
		if(!result.containsKey("nsid")){
			result.put("nsid", "0");
		}
		
		return result;
	}
	
	private String connectReturnString(String url,NameValuePair[] postData){
		String result = "";
		
		if("true".equals(PropsUtil.getProperty(PropsKeys.NODE_CHAT_SYNC_DISENABLE))){
			return result;
		}
		
		url = PropsUtil.getProperty(PropsKeys.NODE_CHAT_DOMAIN) + url;
		HttpClient httpClient = new HttpClient(new SimpleHttpConnectionManager(true));
		httpClient.getParams().setParameter(HttpMethodParams.HTTP_CONTENT_CHARSET, "utf-8");
		PostMethod postMethod = new PostMethod(url);
		
		postMethod.setRequestBody(postData);
		
		try {
			int statusCode = httpClient.executeMethod(postMethod);
			
			if(statusCode == HttpStatus.SC_OK || statusCode == HttpStatus.SC_ACCEPTED){
				byte[] responseBody = postMethod.getResponseBody();
				result = new String(responseBody);
			}else{
				result = "node-chat " + url + " statusCode error , statusCode:" + statusCode;
				_log.error(result);
			}
		} catch (Exception e) {
			result = "node-chat " + url + " connection fail";
			_log.error(result,e);
		}finally{
			postMethod.releaseConnection();
		}
		
		return result;
	}
	
	private NameValuePair[] createNameValuePair(Map<String,String> map){
		int size = map.size(),i = 2;
		NameValuePair[] pair = new NameValuePair[size + 2];
		
		pair[0] = new NameValuePair("appKey",PropsUtil.getProperty(PropsKeys.NODE_CHAT_APPKEY));
		pair[1] = new NameValuePair("masterSecret",PropsUtil.getProperty(PropsKeys.NODE_CHAT_MASTERSECRET));

        Iterator<Map.Entry<String,String>> it = map.entrySet().iterator();
        while(it.hasNext()){
            Map.Entry<String,String> entry = it.next();
            pair[i] = new NameValuePair(entry.getKey(),entry.getValue());
            i++;
        }

		
		return pair;
	}


    /**
     * {
     *  "id": {blogId},
     *  "type": "incoming"
     * }
     * @param userMap
     * @return
     */
    public boolean pushBlogByTagIds(Map<String,String> userMap){
        NameValuePair[] postData = createNameValuePair(userMap);

        return connect("/trust-api/broadcast",postData);
    }
}
